class LimitPromise {
  constructor(max) {
    // 异步任务的并发上限
    this._max = max;
    // 当前正在执行的任务数量
    this._count = 0;
    // 等待执行的任务队列
    this._taskQueue = [];
    this.instance = null;
  }

  run(caller) {
    return new Promise((resolve, reject) => {
      // 创建一个任务
      const task = this._createTask(caller, resolve, reject);

      // 当前队列任务数量是否达到上限
      if (this._count >= this._max) {
        this._taskQueue.push(task);
      } else {
        task();
      }
    });
  }

  _createTask(caller, resolve, reject) {
    return () => {
      caller()
        .then((res) => resolve(res))
        .catch((err) => reject(err))
        .finally(() => {
          this._count--;
          if (this._taskQueue.length) {
            const task = this._taskQueue.shift();
            task();
          }
        });
      this._count++;
    };
  }

  static getInstance(max) {
    if (!this.instance) {
      this.instance = new LimitPromise(max);
    }
    return this.instance;
  }
}
